package com.cxs.service.impl;

import com.cxs.dto.AddCashierProDTO;
import com.cxs.enums.HospitalErrorResultEnum;
import com.cxs.exception.HospitalException;
import com.cxs.mapper.CashierMapper;
import com.cxs.mapper.PharmacyMapper;
import com.cxs.pojo.Cashier;
import com.cxs.pojo.CashierExample;
import com.cxs.pojo.Pharmacy;
import com.cxs.pojo.PharmacyExample;
import com.cxs.service.CashierService;
import com.cxs.vo.Result;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/*
 * @Author:cxs
 * @Date:2021/10/20  20:34
 * @Version 1.0
 * @Motto:放下杂念,只为迎接明天更好的自己
 * */
@Slf4j
@Service
public class CashierServiceImpl implements CashierService {

    @Autowired
    private CashierMapper cashierMapper;

    @Autowired
    private PharmacyMapper pharmacyMapper;


    @Override
    public Result checkHasNoCh(Integer reportId) {
        Boolean isTrue = true;

        CashierExample example = new CashierExample();

        CashierExample.Criteria criteria = example.createCriteria();

        criteria.andReportIdEqualTo(reportId);

        List<Cashier> cashierList = cashierMapper.selectByExample(example);

        for (Cashier c : cashierList) {
            if (c.getState() == 0) {
                isTrue = false;
                break;
            }
        }
        if (isTrue) {
            return Result.Ok();
        } else {
            return Result.failare();
        }
    }

    @Override
    public Result checkHasNoPro(Integer reportId) {
        Boolean isTrue = true;

        CashierExample example = new CashierExample();

        CashierExample.Criteria criteria = example.createCriteria();

        criteria.andReportIdEqualTo(reportId);

        List<Cashier> cashierList = cashierMapper.selectByExample(example);

        for (Cashier c : cashierList) {
            if (c.getState() == 1) {
                isTrue = false;
                break;
            }
        }
        if (isTrue) {
            return Result.Ok();
        } else {
            return Result.failare();
        }
    }

    @Override
    public PageInfo<Cashier> selAllByReportIdPage(Integer reportId, Integer pageNo, Integer limit) {
        PageHelper.startPage(pageNo, limit);
        List<Cashier> cashierList = cashierMapper.selAllByReportId(reportId,0);
        return new PageInfo<>(cashierList);
    }

    @Override
    public Result checkDrupExist(Integer reportId, String mename) {

        CashierExample example = new CashierExample();

        CashierExample.Criteria criteria = example.createCriteria();
        // 按照病人id和药品名查询
        criteria.andReportIdEqualTo(reportId);
        criteria.andDurgNameEqualTo(mename);
        // 分类是药品出纳
        criteria.andStateEqualTo(0);
        // 还没有缴费
        criteria.andMstateEqualTo(0);

        List<Cashier> cashierList = cashierMapper.selectByExample(example);

        if (cashierList.size() == 0) {
            return Result.Ok(0, "");
        }
        return Result.Ok(1, "");
    }

    @Override
    @Transactional
    public void add(Cashier c) {
        // 减掉库存
        updateResp(c);
        // 开药
        int result = cashierMapper.insertSelective(c);

        if (result != 1) {
            log.error("【药品划价】:添加药品失败 report = {}", c);
            throw new HospitalException(HospitalErrorResultEnum.CASHIER_ADD_ERROR);
        }
    }

    @Override
    @Transactional
    public void del(Integer id) {
        // 查询
        Cashier cashier = cashierMapper.selectByPrimaryKey(id);

        // 删除
        int result = cashierMapper.deleteByPrimaryKey(id);

        if (result != 1) {
            log.error("【药品划价】:药品删除失败 id = {}", id);
            throw new HospitalException(HospitalErrorResultEnum.CASHIER_DELETE_ERROR);
        }

        // 恢复库存
        PharmacyExample example = new PharmacyExample();
        PharmacyExample.Criteria criteria = example.createCriteria();
        criteria.andPharmacyNameEqualTo(cashier.getDurgName());
        List<Pharmacy> pharmacyList = pharmacyMapper.selectByExample(example);
        if (pharmacyList == null || pharmacyList.size() == 0) {
            log.error("【药品划价】: 更新药品余量出错");
            throw new HospitalException(HospitalErrorResultEnum.NO_KNOWEN_ERROR);
        }

        Pharmacy pharmacy = pharmacyList.get(0);

        Pharmacy p = new Pharmacy();
        p.setPharmacyId(pharmacy.getPharmacyId());
        p.setDrugStoreNum(pharmacy.getDrugStoreNum() + cashier.getDurgNum());

        int i = pharmacyMapper.updateByPrimaryKeySelective(p);
        if (i != 1) {
            log.error("【药品划价】:药品库存修改失败 {}", p);
            throw new HospitalException(HospitalErrorResultEnum.CASHIER_ADD_ERROR);
        }
    }

    @Override
    public void update(Cashier c) {
        // 获得开过的信息
        CashierExample e = new CashierExample();
        CashierExample.Criteria c1 = e.createCriteria();
        c1.andDurgNameEqualTo(c.getDurgName());
        List<Cashier> cashierList = cashierMapper.selectByExample(e);

        if (cashierList == null || cashierList.size() == 0) {
            log.error("【药品划价】: 查询已有药品出错");
            throw new HospitalException(HospitalErrorResultEnum.NO_KNOWEN_ERROR.getCode(),"查询已有药品出错");
        }

        Cashier cashier = cashierList.get(0);

        updateResp(c);

        // 更新数据
        Integer num = cashier.getDurgNum() + c.getDurgNum();
        Double total = cashier.getRepicePrice();

        Cashier c0 = new Cashier();
        c0.setCashierId(cashier.getCashierId());
        c0.setDurgNum(num);
        c0.setRepiceTotal(num * total);

        int i = cashierMapper.updateByPrimaryKeySelective(c0);

        if (i != 1) {
            log.error("【药品划价】:修改失败 {}", c);
            throw new HospitalException(HospitalErrorResultEnum.CASHIER_UPDATE_ERROR);
        }
    }

    @Override
    public PageInfo<Cashier> selAllByOutReportIdPage(Integer reportId, Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<Cashier> cashierList = cashierMapper.selAllByReportId(reportId,1);
        return new PageInfo<>(cashierList);
    }

    @Override
    public void delete(Integer cashierId) {
        int result = cashierMapper.deleteByPrimaryKey(cashierId);

        if (result != 1) {
            log.error("【项目划价】:药品删除失败 cashierId = {}", cashierId);
            throw new HospitalException(HospitalErrorResultEnum.CASHIER_DELETE_ERROR);
        }
    }

    @Override
    public void addPro(AddCashierProDTO cashierProDTO) {
        Cashier cashier = new Cashier();
        BeanUtils.copyProperties(cashierProDTO,cashier);

        int result = cashierMapper.insertSelective(cashier);

        if (result != 1) {
            log.error("【项目划价】:项目添加失败 cashier = {}", cashier);
            throw new HospitalException(HospitalErrorResultEnum.CASHIER_INSERT_ERROR);
        }
    }

    @Override
    public Result checkProExist(Integer reportId, String durgName) {
        CashierExample example = new CashierExample();

        CashierExample.Criteria criteria = example.createCriteria();
        // 按照病人id和药品名查询
        criteria.andReportIdEqualTo(reportId);
        criteria.andDurgNameEqualTo(durgName);
        // 分类是项目出纳
        criteria.andStateEqualTo(1);
        // 还没有缴费
        criteria.andMstateEqualTo(0);

        List<Cashier> cashierList = cashierMapper.selectByExample(example);

        if (cashierList.size() == 0) {
            return Result.Ok(200, "",0);
        }
        return Result.Ok(200, "",1);
    }

    @Override
    public void updatePro(AddCashierProDTO cashierProDTO) {

        Cashier c = new Cashier();
        BeanUtils.copyProperties(cashierProDTO,c);

        // 获得开过的信息
        CashierExample e = new CashierExample();
        CashierExample.Criteria c1 = e.createCriteria();
        c1.andDurgNameEqualTo(c.getDurgName());
        c1.andReportIdEqualTo(c.getReportId());
        c1.andMstateEqualTo(0);
        List<Cashier> cashierList = cashierMapper.selectByExample(e);

        if (cashierList == null || cashierList.size() == 0) {
            log.error("【药品划价】: 查询已有药品出错");
            throw new HospitalException(HospitalErrorResultEnum.NO_KNOWEN_ERROR.getCode(),"查询已有药品出错");
        }

        Cashier cashier = cashierList.get(0);

        // 更新数据
        Integer num = cashier.getDurgNum() + c.getDurgNum();
        Double total = cashier.getRepicePrice();

        Cashier c0 = new Cashier();
        c0.setCashierId(cashier.getCashierId());
        c0.setDurgNum(num);
        c0.setRepiceTotal(num * total);

        int i = cashierMapper.updateByPrimaryKeySelective(c0);

        if (i != 1) {
            log.error("【项目划价】:修改失败 {}", c);
            throw new HospitalException(HospitalErrorResultEnum.CASHIER_UPDATE_ERROR);
        }
    }

    private void updateResp(Cashier c) {
        // 减掉库存
        Integer num = c.getDurgNum();
        String name = c.getDurgName();

        PharmacyExample example = new PharmacyExample();
        PharmacyExample.Criteria criteria = example.createCriteria();
        criteria.andPharmacyNameEqualTo(name);
        List<Pharmacy> pharmacyList = pharmacyMapper.selectByExample(example);
        if (pharmacyList == null || pharmacyList.size() == 0) {
            log.error("【药品划价】: 更新药品余量出错");
            throw new HospitalException(HospitalErrorResultEnum.NO_KNOWEN_ERROR);
        }

        Pharmacy pharmacy = pharmacyList.get(0);

        if (pharmacy.getDrugStoreNum() < num) {
            log.error("【药品划价】: 药品库存不足");
            throw new HospitalException(HospitalErrorResultEnum.CASHIER_ADD_ERROR);
        }

        Pharmacy p = new Pharmacy();
        p.setPharmacyId(pharmacy.getPharmacyId());
        p.setDrugStoreNum(pharmacy.getDrugStoreNum() - num);

        int i = pharmacyMapper.updateByPrimaryKeySelective(p);
        if (i != 1) {
            log.error("【药品划价】:药品库存修改失败 {}", p);
            throw new HospitalException(HospitalErrorResultEnum.CASHIER_ADD_ERROR);
        }
    }
}
